#define PUDGE_META_TUPLE_SPEC BOOST_PP_ITERATION()

//template<class T0 , class T1>
//struct tuple<T0,T1,null_tuple_element>
//{
//	typedef T0 t0_type;
//	typedef T1 t1_type;
//
//	T0 t0;
//	T1 t1;
//
//	tuple(T0 t0_, T1 t1_)
//		:	t0(t0_)
//		,	t1(t1_){}
//};

template
	<	BOOST_PP_ENUM_PARAMS(PUDGE_META_TUPLE_SPEC, class T) >
struct tuple<BOOST_PP_ENUM_PARAMS(PUDGE_META_TUPLE_SPEC, T)>
{
#define PUDGE_META_TUPLE_M(Z,N,A) typedef T ## N t ## N ## _type;
	BOOST_PP_REPEAT(PUDGE_META_TUPLE_SPEC, PUDGE_META_TUPLE_M,);
#undef PUDGE_META_TUPLE_M
#define PUDGE_META_TUPLE_M(Z,N,A) T ## N t ## N;
	BOOST_PP_REPEAT(PUDGE_META_TUPLE_SPEC, PUDGE_META_TUPLE_M,);
#undef PUDGE_META_TUPLE_M
#define PUDGE_META_TUPLE_M(Z,N,A) T ## N t ## N ## _
	tuple(BOOST_PP_ENUM(PUDGE_META_TUPLE_SPEC, PUDGE_META_TUPLE_M,))
#undef PUDGE_META_TUPLE_M
#define PUDGE_META_TUPLE_M(Z,N,A) t ## N (t ## N ## _)
		:	BOOST_PP_ENUM(PUDGE_META_TUPLE_SPEC, PUDGE_META_TUPLE_M,) {}
#undef PUDGE_META_TUPLE_M
};

//template<> struct tuple_element<0>
//{
//	template<class T> struct result{ typedef typename T::t0_type type; };
//	template<class T> typename deref<typename T::t0_type>::type & operator()(T & t) { return t.t0;}
//};

#define PUDGE_META_TUPLE_ETYPE(N) BOOST_PP_CAT(t, N)_type
#define PUDGE_META_TUPLE_ERET(N) BOOST_PP_CAT(return t.t, N)

template<> struct tuple_element<PUDGE_META_TUPLE_SPEC>
{
	template<class T> struct result
	{ 
		typedef typename T :: PUDGE_META_TUPLE_ETYPE(PUDGE_META_TUPLE_SPEC) type;
	};
	template<class T> 
	typename deref<typename T :: PUDGE_META_TUPLE_ETYPE(PUDGE_META_TUPLE_SPEC)> :: type &
		operator()(T & t) { PUDGE_META_TUPLE_ERET(PUDGE_META_TUPLE_SPEC); }
};